package logic

import (
	"context"
	"github.com/jinzhu/copier"
	"github.com/zeromicro/go-zero/core/mr"
	"mall/app/product/cmd/rpc/internal/svc"
	"mall/app/product/cmd/rpc/pb"
	"mall/app/product/model"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetProductDetailLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetProductDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetProductDetailLogic {
	return &GetProductDetailLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetProductDetailLogic) GetProductDetail(in *pb.GetProductDetailReq) (*pb.GetProductDetailResp, error) {

	var skuInfo *model.PmsSkuInfo
	var images []*model.PmsSkuImages
	var err error
	err = mr.Finish(func() error {
		// 获取sku基本信息
		skuInfo, err = l.svcCtx.SkuInfoModel.FindOne(l.ctx, in.SkuId)
		if err != nil {
			logx.Error(err)
		}
		return err
	}, func() error {
		// 获取sku的图片信息
		images, err = l.svcCtx.SkuImagesModel.FindSkuImagesBySkuId(l.ctx, in.SkuId)
		if err != nil {
			logx.Error(err)
		}
		return err
	})
	if err != nil {
		return nil, err
	}

	spuId := skuInfo.SpuId
	categoryId := skuInfo.CatalogId

	var spuDes *model.PmsSpuInfoDesc
	var saleAttrs []model.SaleAttrResult
	var resList []model.ProductDetailResult
	err = mr.Finish(func() error {
		// 获取spu的介绍
		spuDes, err = l.svcCtx.SpuInfoDescModel.FindOne(l.ctx, spuId)
		if err != nil {
			logx.Error(err)
		}
		return err
	}, func() error {
		saleAttrs, err = l.svcCtx.SkuInfoModel.FindSaleAttrsBySpuId(l.ctx, spuId)
		if err != nil {
			logx.Error(err)
		}
		return err
	}, func() error {
		resList, err = l.svcCtx.ProductAttrValueModel.FindProductDetail(l.ctx, categoryId, spuId)
		if err != nil {
			logx.Error(err)
		}
		return err
	})
	if err != nil {
		return nil, err
	}

	// 处理groupVo的数据格式问题, 和对象转换
	mp := make(map[string][]int)
	for index, item := range resList {
		if v, ok := mp[item.AttrGroupName]; ok {
			tmp := make([]int, len(v))
			copy(tmp, v)
			tmp = append(tmp, index)
			mp[item.AttrGroupName] = tmp
		} else {
			mp[item.AttrGroupName] = []int{index}
		}
	}
	var list []*pb.SpuItemAttrGroupVo
	for k, v := range mp {
		tmp := &pb.SpuItemAttrGroupVo{GroupName: k, Attrs: []*pb.SpuBaseAttrVo{}}
		for _, value := range v {
			attrName := resList[value].AttrName
			attrValue := resList[value].AttrValue
			tmp.Attrs = append(tmp.Attrs, &pb.SpuBaseAttrVo{AttrName: attrName, AttrValues: attrValue})
		}
		list = append(list, tmp)
	}

	var info = new(pb.SkuInfoEntity)
	var imageList []*pb.SkuImageEntity
	var des = new(pb.SpuInfoDesc)
	var saleAttrList []*pb.SkuItemSaleAttrVo

	_ = copier.Copy(&info, skuInfo)
	_ = copier.Copy(&imageList, &images)
	_ = copier.Copy(&des, spuDes)
	_ = copier.Copy(&saleAttrList, saleAttrs)

	return &pb.GetProductDetailResp{
		Info:     info,
		SaleAttr: saleAttrList,
		Images:   imageList,
		Desc:     des,
		GroupVo:  list,
	}, nil
}
